package cn.touna.jss.common.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.util.Assert;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;


/**
 * 类型转换工具类
 */
public class ConvertUtil {
    private static final Logger LOGGER = LogManager.getLogger(ConvertUtil.class);
    public static final String DATE_SMALL_STR = "yyyy-MM-dd HH:mm:ss";

    private ConvertUtil() {
    }

    public static <T> List<T> transfList(Class clz, List origList) throws InvocationTargetException, IllegalAccessException, InstantiationException {
        List<T> destList = new ArrayList<>();
        if (origList != null && origList.size() != 0) {
            T destObj;
            for (int i = 0; i < origList.size(); i++) {
                destObj = (T) clz.newInstance();
                BeanUtils.copyProperties(destObj, origList.get(i));
                destList.add(destObj);
            }
        }
        return destList;
    }


    /**
     * 将一个 JavaBean 对象转化为一个  Map
     *
     * @param bean 要转化的JavaBean 对象
     * @return 转化出来的  Map 对象
     * @throws IntrospectionException    如果分析类属性失败
     * @throws IllegalAccessException    如果实例化 JavaBean 失败
     * @throws InvocationTargetException 如果调用属性的 setter 方法失败
     */
    public static Map convertBean2Map(Object bean) {
        Assert.notNull(bean);
        Class type = bean.getClass();
        Map returnMap = new HashMap();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(type);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (int i = 0; i < propertyDescriptors.length; i++) {
                PropertyDescriptor descriptor = propertyDescriptors[i];
                String propertyName = descriptor.getName();
                if (!propertyName.equals("class")) {
                    Method readMethod = descriptor.getReadMethod();
                    Object result = readMethod.invoke(bean, new Object[0]);
                    if (result != null) {
                        returnMap.put(propertyName, result);
                    } else {
                        returnMap.put(propertyName, "");
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return returnMap;
    }


    /**
     * 将一个 JavaBean 对象转化为一个  Map<String,String>
     *
     * @param bean 要转化的JavaBean 对象
     * @return 转化出来的  Map 对象
     * @throws IntrospectionException    如果分析类属性失败
     * @throws IllegalAccessException    如果实例化 JavaBean 失败
     * @throws InvocationTargetException 如果调用属性的 setter 方法失败
     */
    public static Map<String, String> convertBean2MapString(Object bean) {
        Assert.notNull(bean);
        Class type = bean.getClass();
        Map returnMap = new HashMap();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(type);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (int i = 0; i < propertyDescriptors.length; i++) {
                PropertyDescriptor descriptor = propertyDescriptors[i];
                String propertyName = descriptor.getName();
                if (!propertyName.equals("class")) {
                    Method readMethod = descriptor.getReadMethod();
                    Object result = readMethod.invoke(bean, new Object[0]);
                    if (result != null) {
                        returnMap.put(propertyName, String.valueOf(result));
                    } else {
                        returnMap.put(propertyName, "");
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("转换异常", e);
        }
        return returnMap;
    }


   /* public static <T, V> T Map2Obj(Class<T> clz, Map<String, V> map) throws InvocationTargetException, IllegalAccessException, InstantiationException {
        T obj = clz.newInstance();
        ConvertUtilsBean convertUtils = new ConvertUtilsBean();
        convertUtils.register(new DateConvert(), Date.class);
        BeanUtilsBean beanUtils = new BeanUtilsBean(convertUtils, new PropertyUtilsBean());
        beanUtils.populate(obj, map);
        return obj;
    }*/

    private static String assembleGetName(String fieldName) {
        if (StringUtils.isEmpty(fieldName)) {
            return null;
        }
        return new StringBuffer("get").
                append(fieldName.substring(0, 1).toUpperCase()).
                append(fieldName.substring(1))
                .toString();
    }

    private static Method chkGetMethod(Method[] methods, String fieldGetMet) {
        for (Method met : methods) {
            if (fieldGetMet.equals(met.getName())) {
                return met;
            }
        }
        return null;
    }

    private JSONObject parse(String text) {
        return JSONObject.parseObject(text);
    }

}
